diff options
Diffstat (limited to 'app/[lng]/engineering/(engineering)/pq_new')
| -rw-r--r-- | app/[lng]/engineering/(engineering)/pq_new/[vendorId]/[submissionId]/page.tsx | 215 | ||||
| -rw-r--r-- | app/[lng]/engineering/(engineering)/pq_new/page.tsx | 96 |
2 files changed, 0 insertions, 311 deletions
diff --git a/app/[lng]/engineering/(engineering)/pq_new/[vendorId]/[submissionId]/page.tsx b/app/[lng]/engineering/(engineering)/pq_new/[vendorId]/[submissionId]/page.tsx deleted file mode 100644 index 28ce3128..00000000 --- a/app/[lng]/engineering/(engineering)/pq_new/[vendorId]/[submissionId]/page.tsx +++ /dev/null @@ -1,215 +0,0 @@ -import * as React from "react" -import { Metadata } from "next" -import Link from "next/link" -import { notFound } from "next/navigation" -import { ArrowLeft } from "lucide-react" -import { Shell } from "@/components/shell" -import { Button } from "@/components/ui/button" -import { Badge } from "@/components/ui/badge" -import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert" -import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" -import { Separator } from "@/components/ui/separator" -import { getPQById, getPQDataByVendorId } from "@/lib/pq/service" -import { unstable_noStore as noStore } from 'next/cache' -import { PQReviewWrapper } from "@/components/pq-input/pq-review-wrapper" - -export const metadata: Metadata = { - title: "PQ 검토", - description: "협력업체의 Pre-Qualification 답변을 검토합니다.", -} - -// 페이지가 기본적으로 동적임을 나타냄 -export const dynamic = "force-dynamic" - -interface PQReviewPageProps { - params: Promise<{ - vendorId: string; - submissionId: string; - }> -} - -export default async function PQReviewPage(props: PQReviewPageProps) { - // 캐시 비활성화 - noStore() - - const params = await props.params - const vendorId = parseInt(params.vendorId, 10) - const submissionId = parseInt(params.submissionId, 10) - - try { - // PQ Submission 정보 조회 - const pqSubmission = await getPQById(submissionId, vendorId) - - // PQ 데이터 조회 (질문과 답변) - const pqData = await getPQDataByVendorId(vendorId, pqSubmission.projectId || undefined) - - // 프로젝트 정보 (프로젝트 PQ인 경우) - const projectInfo = pqSubmission.projectId ? { - id: pqSubmission.projectId, - projectCode: pqSubmission.projectCode || '', - projectName: pqSubmission.projectName || '', - status: pqSubmission.status, - submittedAt: pqSubmission.submittedAt, - } : null - - // PQ 유형 및 상태 레이블 - const typeLabel = pqSubmission.type === "GENERAL" ? "일반 PQ" : "프로젝트 PQ" - const statusLabel = getStatusLabel(pqSubmission.status) - const statusVariant = getStatusVariant(pqSubmission.status) - - // 수정 가능 여부 (SUBMITTED 상태일 때만 가능) - const canReview = pqSubmission.status === "SUBMITTED" - - return ( - <Shell className="gap-6 max-w-5xl"> - <div className="flex items-center justify-between"> - <div className="flex items-center gap-4"> - <Button variant="outline" size="sm" asChild> - <Link href="/evcp/pq_new"> - <ArrowLeft className="w-4 h-4 mr-2" /> - 목록으로 - </Link> - </Button> - <div> - <h2 className="text-2xl font-bold tracking-tight"> - {pqSubmission.vendorName} - {typeLabel} - </h2> - <div className="flex items-center gap-2 mt-1"> - <Badge variant={statusVariant}>{statusLabel}</Badge> - {projectInfo && ( - <span className="text-muted-foreground"> - {projectInfo.projectName} ({projectInfo.projectCode}) - </span> - )} - </div> - </div> - </div> - </div> - - {/* 상태별 알림 */} - {pqSubmission.status === "SUBMITTED" && ( - <Alert> - <AlertTitle>제출 완료</AlertTitle> - <AlertDescription> - 협력업체가 {formatDate(pqSubmission.submittedAt)}에 PQ를 제출했습니다. 검토 후 승인 또는 거부할 수 있습니다. - </AlertDescription> - </Alert> - )} - - {pqSubmission.status === "APPROVED" && ( - <Alert variant="success"> - <AlertTitle>승인됨</AlertTitle> - <AlertDescription> - {formatDate(pqSubmission.approvedAt)}에 승인되었습니다. - </AlertDescription> - </Alert> - )} - - {pqSubmission.status === "REJECTED" && ( - <Alert variant="destructive"> - <AlertTitle>거부됨</AlertTitle> - <AlertDescription> - {formatDate(pqSubmission.rejectedAt)}에 거부되었습니다. - {pqSubmission.rejectReason && ( - <div className="mt-2"> - <strong>사유:</strong> {pqSubmission.rejectReason} - </div> - )} - </AlertDescription> - </Alert> - )} - - <Separator /> - - {/* PQ 검토 컴포넌트 */} - <Tabs defaultValue="review" className="w-full"> - <TabsList> - <TabsTrigger value="review">PQ 검토</TabsTrigger> - <TabsTrigger value="vendor-info">협력업체 정보</TabsTrigger> - </TabsList> - - <TabsContent value="review" className="mt-4"> - <PQReviewWrapper - pqData={pqData} - vendorId={vendorId} - pqSubmission={pqSubmission} - canReview={canReview} - /> - </TabsContent> - - <TabsContent value="vendor-info" className="mt-4"> - <div className="rounded-md border p-4"> - <h3 className="text-lg font-medium mb-4">협력업체 정보</h3> - <div className="grid grid-cols-2 gap-4"> - <div> - <p className="text-sm font-medium text-muted-foreground">업체명</p> - <p>{pqSubmission.vendorName}</p> - </div> - <div> - <p className="text-sm font-medium text-muted-foreground">업체 코드</p> - <p>{pqSubmission.vendorCode}</p> - </div> - <div> - <p className="text-sm font-medium text-muted-foreground">상태</p> - <p>{pqSubmission.vendorStatus}</p> - </div> - {/* 필요시 추가 정보 표시 */} - </div> - </div> - </TabsContent> - </Tabs> - </Shell> - ) - } catch (error) { - console.error("Error loading PQ:", error) - notFound() - } -} - -// 상태 레이블 함수 -function getStatusLabel(status: string): string { - switch (status) { - case "REQUESTED": - return "요청됨"; - case "IN_PROGRESS": - return "진행 중"; - case "SUBMITTED": - return "제출됨"; - case "APPROVED": - return "승인됨"; - case "REJECTED": - return "거부됨"; - default: - return status; - } -} - -// 상태별 Badge 스타일 -function getStatusVariant(status: string): "default" | "outline" | "secondary" | "destructive" | "success" { - switch (status) { - case "REQUESTED": - return "outline"; - case "IN_PROGRESS": - return "secondary"; - case "SUBMITTED": - return "default"; - case "APPROVED": - return "success"; - case "REJECTED": - return "destructive"; - default: - return "outline"; - } -} - -// 날짜 형식화 함수 -function formatDate(date: Date | null) { - if (!date) return "날짜 없음"; - return new Date(date).toLocaleDateString("ko-KR", { - year: "numeric", - month: "long", - day: "numeric", - hour: "2-digit", - minute: "2-digit" - }); -}
\ No newline at end of file diff --git a/app/[lng]/engineering/(engineering)/pq_new/page.tsx b/app/[lng]/engineering/(engineering)/pq_new/page.tsx deleted file mode 100644 index 6598349b..00000000 --- a/app/[lng]/engineering/(engineering)/pq_new/page.tsx +++ /dev/null @@ -1,96 +0,0 @@ -import * as React from "react" -import { Metadata } from "next" -import { type SearchParams } from "@/types/table" -import { getValidFilters } from "@/lib/data-table" -import { Shell } from "@/components/shell" -import { DataTableSkeleton } from "@/components/data-table/data-table-skeleton" -import { searchParamsPQReviewCache } from "@/lib/pq/validations" -import { getPQSubmissions } from "@/lib/pq/service" -import { PQSubmissionsTable } from "@/lib/pq/pq-review-table-new/vendors-table" - -export const metadata: Metadata = { - title: "PQ 검토/실사 의뢰", - description: "", -} - -interface PQReviewPageProps { - searchParams: Promise<SearchParams> -} - -export default async function PQReviewPage(props: PQReviewPageProps) { - const searchParams = await props.searchParams - const search = searchParamsPQReviewCache.parse(searchParams) - const validFilters = getValidFilters(search.filters) - - // 디버깅 로그 추가 - console.log("=== PQ Page Debug ==="); - console.log("Raw searchParams:", searchParams); - console.log("Raw basicFilters param:", searchParams.basicFilters); - console.log("Raw pqBasicFilters param:", searchParams.pqBasicFilters); - console.log("Parsed search:", search); - console.log("search.filters:", search.filters); - console.log("search.basicFilters:", search.basicFilters); - console.log("search.pqBasicFilters:", search.pqBasicFilters); - console.log("validFilters:", validFilters); - - // 기본 필터 처리 (통일된 이름 사용) - let basicFilters = [] - if (search.basicFilters && search.basicFilters.length > 0) { - basicFilters = search.basicFilters - console.log("Using search.basicFilters:", basicFilters); - } else if (search.pqBasicFilters && search.pqBasicFilters.length > 0) { - // 하위 호환성을 위해 기존 이름도 지원 - basicFilters = search.pqBasicFilters - console.log("Using search.pqBasicFilters:", basicFilters); - } else { - console.log("No basic filters found"); - } - - // 모든 필터를 합쳐서 처리 - const allFilters = [...validFilters, ...basicFilters] - - console.log("Final allFilters:", allFilters); - - // 조인 연산자도 통일된 이름 사용 - const joinOperator = search.basicJoinOperator || search.pqBasicJoinOperator || search.joinOperator || 'and'; - console.log("Final joinOperator:", joinOperator); - - // Promise.all로 감싸서 전달 - const promises = Promise.all([ - getPQSubmissions({ - ...search, - filters: allFilters, - joinOperator, - }) - ]) - - return ( - <Shell className="gap-4"> - <div className="flex items-center justify-between space-y-2"> - <div className="flex items-center justify-between space-y-2"> - <div> - <h2 className="text-2xl font-bold tracking-tight"> - PQ 검토/실사 의뢰 - </h2> - </div> - </div> - </div> - - {/* Items처럼 직접 테이블 렌더링 */} - <React.Suspense - key={JSON.stringify(searchParams)} // URL 파라미터가 변경될 때마다 강제 리렌더링 - fallback={ - <DataTableSkeleton - columnCount={8} - searchableColumnCount={2} - filterableColumnCount={3} - cellWidths={["10rem", "15rem", "12rem", "12rem", "8rem", "8rem", "10rem", "8rem"]} - shrinkZero - /> - } - > - <PQSubmissionsTable promises={promises} /> - </React.Suspense> - </Shell> - ) -}
\ No newline at end of file |
